<!--
 * @Author: 徐建辰
 * @Date: 2022-05-27 10:00:56
 * @LastEditTime: 2022-06-21 08:58:44
 * @LastEditors: xjc
 * @Description: 右键菜单组件
-->
<template>
  <transition name="el-zoom-in-top">
		<div 
      v-show="visible" 
      ref="contextmenuRef" 
      class="contextmenu" 
      :style="{left:left+'px',top:top+'px'}" 
      @contextmenu.prevent="openMenu"
    >
			<ul class="contextmenu__menu">
				<slot />
			</ul>
		</div>
	</transition>
</template>

<script setup>
import {provide, ref, watch, nextTick} from 'vue'

provide('menuClick', menuClick)

// eslint-disable-next-line
const emits = defineEmits(['command', 'visibleChange'])

const contextmenuRef = ref(null)
const visible = ref(false)
const top = ref(0)
const left = ref(0)

watch(visible, newVal => {
  if (newVal) {
    document.body.addEventListener('click', cm, true)
  } else {
    document.body.removeEventListener('click', cm, true)
  }
})

function cm(e){
  let sp = contextmenuRef.value
  if (sp && !sp.contains(e.target)) {
    closeMenu()
  }
}
function menuClick(command){
  closeMenu()
  emits('command', command)
}
function openMenu(e) {
  e.preventDefault()
  visible.value = true
  left.value = e.clientX + 1
  top.value = e.clientY + 1

  nextTick(() => {
    const cmRef = contextmenuRef.value
    const ex = e.clientX + 1
    const ey = e.clientY + 1
    const innerWidth = window.innerWidth
    const innerHeight = window.innerHeight
    const menuHeight = cmRef.offsetHeight
    const menuWidth = cmRef.offsetWidth
    // 位置修正公示
    // left = (当前点击X + 菜单宽度 > 可视区域宽度 ? 可视区域宽度 - 菜单宽度 : 当前点击X)
    // top = (当前点击Y + 菜单高度 > 可视区域高度 ? 当前点击Y - 菜单高度 : 当前点击Y)
    left.value = ex + menuWidth > innerWidth ? innerWidth - menuWidth : ex
    top.value = ey + menuHeight > innerHeight ? ey - menuHeight : ey
  })
  emits('visibleChange', true)
}
function closeMenu() {
  visible.value = false
  emits('visibleChange', false)
}
function fun(){
  visible.value = true
}

// eslint-disable-next-line no-undef
defineExpose({openMenu, close, fun})
</script>

<style scoped lang="scss">
@import './index.scss';
</style>
